home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / lpDaemon SRC / lpd Sources / Spooler.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-24  |  8.3 KB  |  320 lines  |  [TEXT/KAHL]

  1. /************************************************************************
  2.  *                                                                        *
  3.  * Spooler.C                                                            *
  4.  *                                                                        *
  5.  *  Line Printer Daemon using TCP/IP printer protocol                    *
  6.  *                                                                        *
  7.  *    -------------- The spool file maintenance routines --------------    *
  8.  *                                                                        *
  9.  *  Written by Casper Boon, July, 1992.                                    *
  10.  *                                                                        *
  11.  *    © 1992, Casper Boon.                                                *
  12.  *                                                                        *
  13.  ************************************************************************/
  14.  
  15. #include "LPD.H"
  16. #include "lpdProtos.H"
  17. #include "Spooler.H"
  18. #include "BackGrounder.H"
  19.  
  20.  
  21. Boolean     printing = FALSE;
  22. extern integer    spool_dir;
  23. extern prtHandle printers;
  24. extern char *cfA;
  25.  
  26. static printParm prints[4];
  27.  
  28.  
  29. /************************************************************************
  30.  ************************************************************************/
  31. /* print the next buffer load */
  32. void Poke_Spooler()
  33. {
  34.     integer fRef;
  35.     Byte    printer[100];
  36.     Str255    name_buf;
  37.     integer which_prt, cfRef;
  38.     ctl_def    cctl;
  39.     prtPtr    prtr = *printers;
  40.     integer    nPrtrs = GetHandleSize((Handle)printers) / sizeof(prtRecord);
  41.  
  42.     if (noAction) return;        /* debugging */
  43.  
  44.     if (printing)
  45.         {
  46.         if DEBUGGING log_printf("Spooler poked while printing\n");
  47.         return;
  48.         }
  49.  
  50.     if ( GetFile(name_buf, &cctl) )    /* find a control file */
  51.         {
  52.         Quitable = FALSE;
  53.         printing = TRUE;
  54.  
  55.         which_prt = 2;
  56.         while (nPrtrs--)
  57.             {
  58.             if ( strcmp(cctl.printer, prtr->in_name)==0 )
  59.                 break;
  60.             prtr++;
  61.             }
  62.  
  63.         if (nPrtrs < 0)
  64.             {
  65.             Handle elog = NewHandle(0);
  66.             char    buf[128];
  67.  
  68.             sprintf(buf, "No such printer?? \"%s\"\n", cctl.printer);
  69.             log_printf(buf);
  70.  
  71.             LogError("\015\012\015\012Printing to ", elog);
  72.             LogError(cctl.printer, elog);
  73.             LogError("\015\012\015\012", elog);
  74.             LogError(buf, elog);
  75.             if (mailing) SendMail(cctl.owner, cctl.host, elog, 0);
  76.             DisposHandle(elog);
  77.  
  78.             DeleteSpoolFile(name_buf);
  79.             printing = FALSE;
  80.             Quitable = TRUE;
  81.             Poke_Spooler();
  82.             return;
  83.             }
  84.         else if DEBUGGING
  85.             log_printf("No files found when spooler poked\n");
  86.  
  87.         name_buf[1] = cfA[0];    /* make sure! */
  88.         if (FSOpenRO(name_buf, spool_dir, &cfRef))
  89.             return ;        /* error opening control file */
  90.  
  91.         prints[which_prt=nPrtrs].prtr = prtr;
  92.  
  93.         if (prtr->outname[0])
  94.             prints[which_prt].printer = prtr->outname;
  95.         else
  96.             prints[which_prt].printer = NIL;
  97.         prints[which_prt].cfRef = cfRef;
  98.         BlockMove(name_buf, prints[which_prt].name_buf, name_buf[0] + 1);
  99.  
  100.         BlockMove((Ptr)&cctl, (Ptr)&prints[which_prt].cctl, sizeof(cctl));
  101.  
  102.         prints[which_prt].elog = NewHandle(0);
  103.  
  104.         /* print all files for this job */
  105.         NextFile(which_prt);
  106.         }
  107. }
  108.  
  109.  
  110. /************************************************************************
  111.  ************************************************************************/
  112. void NextFile(integer which_prt)
  113. {
  114.     integer count = 0;
  115.     char    buf[100];
  116.     Byte    prt_name_buf[100];
  117.     Boolean    literal, found = FALSE;
  118.     LongInt    bytes;
  119.     OSErr    err;
  120.  
  121.     while ( ReadLine(prints[which_prt].cfRef, buf, 98) )
  122.         {
  123.         if (buf[0] != 'f' && buf[0] != 'l')    /* the spool file name ? */
  124.             continue;
  125.  
  126.         literal = (buf[0] == 'l');
  127.  
  128.         BlockMove(&buf[1], &prt_name_buf[1], strlen(&buf[1]));
  129.         prt_name_buf[0] = strlen(&buf[1]);
  130.  
  131.         while ( ReadLine(prints[which_prt].cfRef, buf, 98) )
  132.             {    /* look for source file name */
  133.             if (buf[0] == 'N')    /* the source file name ? */
  134.                 break;
  135.             }
  136.  
  137.         log_printf("Printing %s for %s@%s on \"%s\"\n",
  138.                                 &buf[1], prints[which_prt].cctl.owner,
  139.                                          prints[which_prt].cctl.host,
  140.                                          prints[which_prt].cctl.printer);
  141.  
  142.         /* add the name of the file to the error log */
  143.         prints[which_prt].prev_len = GetHandleSize(prints[which_prt].elog);
  144.         LogError("\015\012\015\012Printing file ", prints[which_prt].elog);
  145.         LogError(&buf[1], prints[which_prt].elog);
  146.         LogError("\015\012\015\012", prints[which_prt].elog);
  147.         prints[which_prt].old_len = GetHandleSize(prints[which_prt].elog);
  148.  
  149.     
  150.         if ((err=FSOpenRO(prt_name_buf, spool_dir, &prints[which_prt].fRef))==noErr)
  151.             {
  152.             if DEBUGGING
  153.                 log_printf("Now starting %p, (%d)\n",
  154.                                     prt_name_buf, prints[which_prt].fRef);
  155.             if (prints[which_prt].prtr->postscript /*is a postscript printer*/)
  156.                 {
  157.                 if DEBUGGING
  158.                     log_printf("Checking for postscript\n");
  159.                 bytes = 2L; FSRead(prints[which_prt].fRef, &bytes, buf);
  160.                 SetFPos(prints[which_prt].fRef, fsFromStart, 0L);    /* set the file bck to the start */
  161.  
  162.                 if (bytes < 2)                    /* an error */
  163.                     {
  164.                     if DEBUGGING
  165.                         log_printf("%p is not long enough\n", prt_name_buf);
  166.  
  167.                     FSClose(prints[which_prt].fRef);
  168.                     continue;
  169.                     }
  170.                     /* the following test for postscript is not the best. It checks if    *
  171.                      * either the first or second byte in a file is a %.  This covers    *
  172.                      * the DOS postscript generators which like to put a page feed as    *
  173.                      * the first byte before the %!.                                    */
  174.                 else if ((buf[0] != '%') && (buf[1] != '%'))
  175.                     {    /* not a postscript file */
  176.                     if DEBUGGING
  177.                         log_printf("%p is NOT postscript\n", prt_name_buf);
  178.  
  179.                     if (!literal && which_prt != 1)    /* not an ImageWriter */
  180.                         {
  181. #ifdef TEXTPS
  182.                         prints[which_prt].fRef = 
  183.                                         textps(prt_name_buf, prints[which_prt].fRef);
  184.                         if (stopped)
  185.                             {
  186.                             stopped = FALSE;
  187.                             continue;
  188.                             }
  189. #else
  190.                         LogError("This is NOT POSTSCRIPT\015\012", prints[which_prt].elog);
  191.                         continue;
  192. #endif
  193.                         }
  194.                     }
  195.                 else
  196.                     {
  197.                     if DEBUGGING
  198.                         log_printf("%p IS a postscript\n", prt_name_buf);
  199.         
  200.                     /* we are ready to print this one */
  201.                     }
  202.                 }
  203.             }
  204.         else    /* file failed to open */
  205.             {
  206.             log_printf("Could not open %p (%d)\n", prt_name_buf, err);
  207.             continue;
  208.             }
  209.  
  210.         found = TRUE;
  211.         break;
  212.         }
  213.  
  214.     if (!found)    /* done all files for this print job */
  215.         {
  216.         FSClose(prints[which_prt].cfRef);
  217.         if ( ( GetHandleSize(prints[which_prt].elog) > 0 ) && mailing )
  218.             SendMail(prints[which_prt].cctl.owner, prints[which_prt].cctl.host, prints[which_prt].elog, 0);
  219.         DeleteSpoolFile(prints[which_prt].name_buf);
  220.         DisposHandle(prints[which_prt].elog);
  221.         printing = FALSE;
  222.         Quitable = TRUE;
  223.         Poke_Spooler();
  224.         return;
  225.         }
  226.  
  227.     prints[which_prt].pstate = 0;
  228.     if (prints[which_prt].prtr->pap)
  229.         PAPDownLoad(prints[which_prt].fRef,
  230.                             prints[which_prt].prtr->postscript,
  231.                                     prints[which_prt].printer,
  232.                                         prints[which_prt].elog,
  233.                                             &prints[which_prt].pstate);
  234.     else
  235.         SerialPrint(prints[which_prt].fRef,
  236.                         prints[which_prt].prtr->postscript,
  237.                             prints[which_prt].printer,
  238.                                 prints[which_prt].prtr->params,
  239.                                         prints[which_prt].elog,
  240.                                             &prints[which_prt].pstate);
  241.  
  242.     Background(&prints[which_prt].pstate, PrintFileDone, (Ptr)which_prt);
  243. }
  244.  
  245.  
  246. /************************************************************************
  247.  ************************************************************************/
  248. void PrintFileDone(integer flag, Ptr param)
  249. {
  250.     integer    index = ((LongWord)param & 0xFFF);
  251.  
  252.     FSClose(prints[index].fRef);
  253.  
  254.     /* if the size hasn't changed, might as well delete the file name */
  255.     if (prints[index].old_len == GetHandleSize(prints[index].elog) )
  256.         SetHandleSize(prints[index].elog, prints[index].prev_len);
  257.     else
  258.         LogError("\015\012\015\012", prints[index].elog);
  259.  
  260.     NextFile(index);
  261. }
  262.  
  263.  
  264. /************************************************************************
  265.  ************************************************************************/
  266. integer GetFile(StringPtr name_buf, ctl_def *ctl)
  267. {
  268.     integer    index = 1;
  269.  
  270.     if ( !EnumerateFiles(spool_dir, &index, name_buf, ctl) )
  271.         return FALSE;
  272.  
  273.     if DEBUGGING
  274.         log_printf("Printing file %p\n", name_buf);
  275.  
  276.     ctl->nextFile = 0;
  277.     return TRUE;
  278. }
  279.  
  280. /************************************************************************
  281.  ************************************************************************/
  282. void SendPostscriptFile()
  283. {
  284.     SFReply    reply;
  285.     Point    aPoint;
  286.     SFTypeList    types;
  287.     integer    fRef, err, pstate;
  288.     extern Boolean    printing;
  289.     Handle    elog;
  290.  
  291.     if (printing)
  292.         {
  293.         SysBeep(5);
  294.         return;
  295.         }
  296.  
  297.     aPoint.h = aPoint.v = 80;
  298.     types[0] = 'TEXT';
  299.     SFGetFile(aPoint, NIL, NIL, 1, types, NIL, &reply);
  300.  
  301.     if ( reply.good == 0 )
  302.         return;
  303.  
  304.     err = FSOpen((StringPtr)reply.fName, reply.vRefNum, &fRef);
  305.     if ( err == -49 )        /* already open somewhere */
  306.         err = FSOpenRO((StringPtr)reply.fName, reply.vRefNum, &fRef);
  307.  
  308.     if ( !err )
  309.         {
  310.         pstate = 1;
  311.         elog = NewHandle(0);
  312.         PAPDownLoad(fRef, TRUE, NIL, elog, &pstate);
  313.         while (pstate > 0)
  314.             MainEvents(everyEvent);
  315.         DisposHandle(elog);
  316.         }
  317.  
  318.     FSClose(fRef);
  319. }
  320.